
#include <assert.h>
#include <time.h>
#include "sdlJeu.h"

const int TAILLE_SPRITE=32;

SDL_Surface *SDL_load_image(const char* filename );
void SDL_apply_surface( SDL_Surface* source, SDL_Surface* destination, int x, int y );



void sdljeuInit(sdlJeu *pSdlJeu)
{
	Jeu *pJeu;
	int dimx, dimy;

	pJeu = &(pSdlJeu->jeu);
	jeuInit(pJeu);

	assert(   SDL_Init( SDL_INIT_EVERYTHING )!= -1 );

	dimx = getDimX( jeuGetConstTerrainPtr(pJeu) );
	dimy = getDimY( jeuGetConstTerrainPtr(pJeu) );
	dimx = dimx * TAILLE_SPRITE;
	dimy = dimy * TAILLE_SPRITE;
	pSdlJeu->surface_ecran = SDL_SetVideoMode(   dimx, dimy, 32, SDL_SWSURFACE );
	assert( pSdlJeu->surface_ecran!=NULL);
	SDL_WM_SetCaption( "Pacman v0.1", NULL );

	pSdlJeu->surface_pacman = SDL_load_image("data/labyrinthe.bmp");
	if (pSdlJeu->surface_pacman==NULL)
		pSdlJeu->surface_pacman = SDL_load_image("../data/labyrinthe.bmp");
	assert( pSdlJeu->surface_pacman!=NULL);

	pSdlJeu->surface_mur = SDL_load_image("data/case.bmp");
	if (pSdlJeu->surface_mur==NULL)
		pSdlJeu->surface_mur = SDL_load_image("../data/case.bmp");
	assert( pSdlJeu->surface_mur!=NULL);

	pSdlJeu->surface_fantome = SDL_load_image("data/joueur.bmp");
	if (pSdlJeu->surface_fantome==NULL)
		pSdlJeu->surface_fantome = SDL_load_image("../data/joueur.bmp");
	assert( pSdlJeu->surface_fantome!=NULL);
}



void sdljeuAff(sdlJeu *pSdlJeu)
{
	int x,y,i_fant;

    const Jeu *pJeu = &(pSdlJeu->jeu);
	const Terrain *pTer = jeuGetConstTerrainPtr(pJeu);
	const Pacman *pPac = jeuGetConstlabyrinthePtr(pJeu);

	/* Remplir l'écran de blanc */
	SDL_FillRect( pSdlJeu->surface_ecran, &pSdlJeu->surface_ecran->clip_rect, SDL_MapRGB( pSdlJeu->surface_ecran->format, 0xFF, 0xFF, 0xFF ) );

	for (x=0;x<getDimX(pTer);++x)
		for (y=0;y<getDimY(pTer);++y)
			if (terGetXY(pTer,x,y)=='#')
				SDL_apply_surface(  pSdlJeu->surface_mur, pSdlJeu->surface_ecran, x*TAILLE_SPRITE, y*TAILLE_SPRITE);

    for (i_fant=0; i_fant<pJeu->nb_joueur; i_jou++)
        SDL_apply_surface(  pSdlJeu->surface_joueur, pSdlJeu->surface_ecran, (pJeu->tab_joueurs[i_fant].x)*TAILLE_SPRITE, (pJeu->tab_joueurs[i_fant].y)*TAILLE_SPRITE);

	/* Copier le sprite de labyrinthe sur l'écran */
	SDL_apply_surface(  pSdlJeu->surface_labyrinthe, pSdlJeu->surface_ecran, pacGetX(pPac)*TAILLE_SPRITE,  pacGetY(pPac)*TAILLE_SPRITE );
}



void sdljeuBoucle(sdlJeu *pSdlJeu)
{
	SDL_Event event;
	int continue_boucle = 1;

    /* Horloges (en secondes) */
    float horloge_courante, horloge_precedente;

    /* Intervalle de temps (en secondes) entre deux évolutions du jeu */
    /* Changer la valeur pour ralentir ou accélérer le déplacement des fantomes */
    float intervalle_horloge = 0.1f;

    int rafraichissement;

	sdljeuAff(pSdlJeu);
	assert( SDL_Flip( pSdlJeu->surface_ecran )!=-1 );

    /* Récupère l'horloge actuelle et la convertit en secondes */
    /* clock() retourne le nombre de tops horloge depuis le lancement du programme */
    horloge_precedente = (float)clock()/(float)CLOCKS_PER_SEC;

	/* Tant que ce n'est pas la fin ... */
	while ( continue_boucle == 1 )
	{
	    rafraichissement = 0;

	     /* Récupère l'horloge actuelle et la convertit en secondes */
        horloge_courante = (float)clock()/(float)CLOCKS_PER_SEC;

        /* Si suffisamment de temps s'est écoulé depuis la dernière prise d'horloge */
        if (horloge_courante-horloge_precedente>=intervalle_horloge)
        {
                jeuEvolue(&(pSdlJeu->jeu));
                rafraichissement = 1;
                horloge_precedente = horloge_courante;
        }

		/* tant qu'il y a des evenements à traiter : cette boucle n'est pas bloquante */
		while ( SDL_PollEvent( &event ) )
		{
			/* Si l'utilisateur a cliqué sur la croix de fermeture */
			if ( event.type == SDL_QUIT )
				continue_boucle = 0;

			/* Si l'utilisateur a appuyé sur une touche */
			if ( event.type == SDL_KEYDOWN )
			{
				switch ( event.key.keysym.sym )
				{
				case SDLK_UP:
					jeuActionClavier( &(pSdlJeu->jeu), 'h');
					rafraichissement = 1;
					break;
				case SDLK_DOWN:
					jeuActionClavier( &(pSdlJeu->jeu), 'b');
					rafraichissement = 1;
					break;
				case SDLK_LEFT:
					jeuActionClavier( &(pSdlJeu->jeu), 'g');
					rafraichissement = 1;
					break;
				case SDLK_RIGHT:
					jeuActionClavier( &(pSdlJeu->jeu), 'd');
					rafraichissement = 1;
					break;
				default: break;
				}
			}

		}

        if (rafraichissement==1)
        {
          
            sdljeuAff(pSdlJeu);

  
            SDL_Flip( pSdlJeu->surface_ecran );
        }
	}
}


void sdljeuLibere( sdlJeu *pSdlJeu)
{
	SDL_FreeSurface( pSdlJeu->surface_labyrinthe );
	SDL_FreeSurface( pSdlJeu->surface_case );
	SDL_FreeSurface( pSdlJeu->surface_joueur );

	jeuLibere(&(pSdlJeu->jeu));

	SDL_Quit();
}



SDL_Surface *SDL_load_image(const char* filename )
{
	SDL_Surface* loadedImage = NULL;

	SDL_Surface* optimizedImage = NULL;

	loadedImage = SDL_LoadBMP( filename );

	if ( loadedImage != NULL )
	{
		optimizedImage = SDL_DisplayFormat( loadedImage );

		SDL_FreeSurface( loadedImage );
	}

	return optimizedImage;
}


void SDL_apply_surface( SDL_Surface* source, SDL_Surface* destination, int x, int y )
{

	SDL_Rect offset;

	offset.x = x;
	offset.y = y;

	SDL_BlitSurface( source, NULL, destination, &offset );
}
